#include<bits/stdc++.h> 
using namespace std;
//	给定一组数字段，需要排出最小的数字。例如{32, 321, 3214, 0229, 87}排序的结果是0229321
//	32143287
//1.每个输入包括一个测试用例，每个测试用例包括一个正整数N≤10000，然后跟着N个数字段，每
//	段包括一个不超过8位的非负整数。
//2.对于每一个测试用例，输出最小的数字。
//3.排序 
vector<string> seg[10];	//这道题的思路其实很简单，有贪心的感觉在里面，我的思路是按照数字段的开头分别存到不同的向量里，然后各个向量内部排序完后，再按照向量0~9输出 
bool cmp(string a,string b){	//排序的方式是取任意两个，然后按照不同顺序拼接起来，比较两个拼接结果，按照小的拼接方式排序。例如32 321 3214是一个向量内的，取32 321，得到32321和32132，后者小，所以321排在32前 
	string ab = a+b;
	string ba = b+a;
	return ab<ba;
}
int main(){
	int N;
	cin>>N;
	for(int i = 0;i<N;i++){
		string temp;
		cin>>temp;
		seg[temp[0]-'0'].push_back(temp);	//按照段首字符存储向量 
	}
	for(int i = 0;i<10;i++){
		if(seg[i].size()>1) sort(seg[i].begin(),seg[i].end(),cmp);	//分别排序 
	}  
	string ans = "";
	for(int i = 0;i<10;i++){
		for(unsigned int j = 0;j<seg[i].size();j++){
			ans += seg[i][j];	//拼接结果 
		}
	}
	bool flag = false;
	for(int i = 0;i<ans.length();i++){
		if(flag==true || ans[i]!='0'){	//去除首0 
			flag = true;
			cout<<ans[i];
		}
	}
	if(flag==false) cout<<0<<endl;
	else cout<<endl;
	return  0;
} 